//
//  FLSocketManager.m
//  
//
//  Created by liuzhu on 2018/9/3.
//  Copyright © 2018年 liuzhu. All rights reserved.
//

#import "FLSocketManager.h"
#import "Reachability.h"
@implementation FLSocketManager
{
    FLAsyncSocket* _asyncSocket;
    NSString* _ip;
    NSInteger _port;
    NSInteger _outTime;
    NSTimer* _outTimer;
    Reachability * _localWiFiReach;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _asyncSocket = [[FLAsyncSocket alloc] init];
        _asyncSocket.delegate = self;
        
        _localWiFiReach = [Reachability reachabilityForLocalWiFi];
        _localWiFiReach.reachableOnWWAN = NO;
        __block FLSocketManager *blockSelf = self;
        _localWiFiReach.reachableBlock = ^(Reachability * reachability){
            [blockSelf reConnect];
        };
        [_localWiFiReach startNotifier];
    }
    return self;
}

-(void)reConnect
{
    [self connectToDeviceWithIp:_ip port:nil timeout:5 reserve:nil];
}

/**
 和设备建立TCP连接

 @param ip 设备在局域网内的ip地址
 @param port 端口号
 @param time 连接设备的超时时间
 @param reserve 备用字段
 */
-(void)connectToDeviceWithIp:(NSString *)ip port:(NSString *)port timeout:(NSInteger)time reserve:(NSDictionary*)reserve
{
    if (self.isConnetced)
    {
        if ([self.delegate respondsToSelector:@selector(socketConnected)])
        {
            [self.delegate socketConnected];
        }
        return;
    }
    _ip = ip;
    _outTime = time;
    if (port)
    {
        _port = [port integerValue];
    }
    else
    {
        _port = 2000;
    }
    if (!_outTimer)
    {
        _outTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(judgeOutTime) userInfo:nil repeats:YES];
    }
    [_asyncSocket connectToHost:_ip onPort:_port error:nil];
    [_asyncSocket readDataWithTimeout:-1 tag:SOCKET_CON_TAG];
}

//判断超时
-(void)judgeOutTime
{
    _outTime--;
    if (_outTime <=0)
    {
        _outTime =0;
        [_outTimer invalidate];
        _outTimer = nil;
        //回调超时方法
        if ([self.delegate respondsToSelector:@selector(socketFailConnected)])
        {
            self.isConnetced = NO;
            [self.delegate socketFailConnected];
        }
    }
}

//断开连接
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)error
{
    self.isConnetced = NO;
    if ([self.delegate respondsToSelector:@selector(socketDisconnected)])
    {
        [self.delegate socketDisconnected];
    }
}

//连接成功
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port
{
    self.isConnetced = YES;
    [_outTimer invalidate];
    _outTimer = nil;
    if ([self.delegate respondsToSelector:@selector(socketConnected)])
    {
        [self.delegate socketConnected];
    }
}

//发送数据
-(void)sendDataWith:(NSString*)dataStr andTag:(NSInteger)tag
{
    NSLog(@"haha:tag:%@",dataStr);
    NSData *aData =[dataStr dataUsingEncoding:NSUTF8StringEncoding];
    [_asyncSocket writeData:aData withTimeout:5 tag:tag];
    [_asyncSocket readDataWithTimeout:-1 tag:tag];
}

//接收数据
- (void)socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
    if (tag == SOCKET_CON_TAG)
    {
        //初始连接时返回
        NSString* message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if ([self.delegate respondsToSelector:@selector(socketReceiveData:andTag:)])
        {
            [self.delegate socketReceiveData:message andTag:tag];
        }
        [_asyncSocket readDataWithTimeout:-1 tag:SOCKET_REC_TAG];
    }
    else if(tag == SOCKET_REC_TAG)
    {   //每次设备主动返回
        NSString* message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if ([self.delegate respondsToSelector:@selector(socketReceiveData:andTag:)])
        {
            [self.delegate socketReceiveData:message andTag:tag];
        }
        [_asyncSocket readDataWithTimeout:-1 tag:SOCKET_REC_TAG];
    }
    else
    {   //发送指令后设备返回的数据
        NSString* message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if ([self.delegate respondsToSelector:@selector(socketReceiveData:andTag:)])
        {
            [self.delegate socketReceiveData:message andTag:tag];
        }
    }
}

-(void)closeSocket
{
    [_asyncSocket disconnect];
    _asyncSocket.delegate = nil;
    [_outTimer invalidate];
    _outTimer = nil;
}
@end
